/**
 * 数据预处理系统通用JavaScript函数
 */

// 全局配置
const CONFIG = {
    API_BASE: '/api',
    REFRESH_INTERVAL: 30000, // 30秒
    REQUEST_TIMEOUT: 30000   // 30秒
};

// 工具函数
const Utils = {
    /**
     * 格式化日期时间
     */
    formatDateTime: function(dateStr) {
        if (!dateStr) return '-';
        const date = new Date(dateStr);
        return date.toLocaleString('zh-CN', {
            year: 'numeric',
            month: '2-digit',
            day: '2-digit',
            hour: '2-digit',
            minute: '2-digit',
            second: '2-digit'
        });
    },

    /**
     * 格式化持续时间
     */
    formatDuration: function(seconds) {
        if (!seconds || seconds < 0) return '-';
        
        if (seconds < 60) {
            return `${seconds}秒`;
        } else if (seconds < 3600) {
            const minutes = Math.floor(seconds / 60);
            const remainingSeconds = seconds % 60;
            return `${minutes}分${remainingSeconds}秒`;
        } else {
            const hours = Math.floor(seconds / 3600);
            const minutes = Math.floor((seconds % 3600) / 60);
            return `${hours}时${minutes}分`;
        }
    },

    /**
     * 格式化文件大小
     */
    formatFileSize: function(bytes) {
        if (!bytes || bytes === 0) return '0 B';
        
        const k = 1024;
        const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    },

    /**
     * 防抖函数
     */
    debounce: function(func, wait, immediate) {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                timeout = null;
                if (!immediate) func.apply(this, args);
            };
            const callNow = immediate && !timeout;
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
            if (callNow) func.apply(this, args);
        };
    },

    /**
     * 节流函数
     */
    throttle: function(func, limit) {
        let inThrottle;
        return function(...args) {
            if (!inThrottle) {
                func.apply(this, args);
                inThrottle = true;
                setTimeout(() => inThrottle = false, limit);
            }
        };
    },

    /**
     * 生成UUID
     */
    generateUUID: function() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            const r = Math.random() * 16 | 0;
            const v = c === 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    },

    /**
     * 深拷贝对象
     */
    deepClone: function(obj) {
        if (obj === null || typeof obj !== 'object') return obj;
        if (obj instanceof Date) return new Date(obj.getTime());
        if (obj instanceof Array) return obj.map(item => this.deepClone(item));
        if (typeof obj === 'object') {
            const clonedObj = {};
            for (let key in obj) {
                if (obj.hasOwnProperty(key)) {
                    clonedObj[key] = this.deepClone(obj[key]);
                }
            }
            return clonedObj;
        }
    },

    /**
     * 验证邮箱格式
     */
    validateEmail: function(email) {
        const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        return re.test(email);
    },

    /**
     * 验证IP地址
     */
    validateIP: function(ip) {
        const re = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
        return re.test(ip);
    },

    /**
     * 验证端口号
     */
    validatePort: function(port) {
        const num = parseInt(port);
        return !isNaN(num) && num >= 1 && num <= 65535;
    }
};

// API请求封装
const API = {
    /**
     * 发送GET请求
     */
    get: function(url, params = {}) {
        return this._request('GET', url, null, params);
    },

    /**
     * 发送POST请求
     */
    post: function(url, data = {}, params = {}) {
        return this._request('POST', url, data, params);
    },

    /**
     * 发送PUT请求
     */
    put: function(url, data = {}, params = {}) {
        return this._request('PUT', url, data, params);
    },

    /**
     * 发送DELETE请求
     */
    delete: function(url, params = {}) {
        return this._request('DELETE', url, null, params);
    },

    /**
     * 基础请求方法
     */
    _request: function(method, url, data, params) {
        // 构建完整URL
        let fullUrl = url.startsWith('http') ? url : CONFIG.API_BASE + url;
        
        // 添加查询参数
        if (params && Object.keys(params).length > 0) {
            const queryString = new URLSearchParams(params).toString();
            fullUrl += (fullUrl.includes('?') ? '&' : '?') + queryString;
        }

        // 请求配置
        const config = {
            method: method,
            headers: {
                'Content-Type': 'application/json',
                'X-Requested-With': 'XMLHttpRequest'
            },
            timeout: CONFIG.REQUEST_TIMEOUT
        };

        // 添加请求体
        if (data && (method === 'POST' || method === 'PUT')) {
            config.body = JSON.stringify(data);
        }

        // 发送请求
        return fetch(fullUrl, config)
            .then(response => {
                if (!response.ok) {
                    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                }
                return response.json();
            })
            .catch(error => {
                console.error('API请求失败:', error);
                throw error;
            });
    }
};

// 通知系统
const Notification = {
    /**
     * 显示成功消息
     */
    success: function(message, title = '成功') {
        this._showAlert(message, 'success', title);
    },

    /**
     * 显示错误消息
     */
    error: function(message, title = '错误') {
        this._showAlert(message, 'danger', title);
    },

    /**
     * 显示警告消息
     */
    warning: function(message, title = '警告') {
        this._showAlert(message, 'warning', title);
    },

    /**
     * 显示信息消息
     */
    info: function(message, title = '信息') {
        this._showAlert(message, 'info', title);
    },

    /**
     * 显示警告框
     */
    _showAlert: function(message, type, title) {
        const alertId = 'alert-' + Utils.generateUUID();
        const alertHtml = `
            <div id="${alertId}" class="alert alert-${type} alert-dismissible fade show" role="alert">
                <h6 class="alert-heading mb-1">
                    <i class="fas fa-${this._getIcon(type)} me-1"></i>${title}
                </h6>
                <div>${message}</div>
                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
            </div>
        `;

        // 添加到页面
        const container = $('.container-fluid').first();
        if (container.length > 0) {
            container.prepend(alertHtml);
        } else {
            $('body').prepend(`<div class="container-fluid">${alertHtml}</div>`);
        }

        // 自动消失
        setTimeout(() => {
            $(`#${alertId}`).alert('close');
        }, 5000);
    },

    /**
     * 获取警告图标
     */
    _getIcon: function(type) {
        const icons = {
            'success': 'check-circle',
            'danger': 'exclamation-circle',
            'warning': 'exclamation-triangle',
            'info': 'info-circle'
        };
        return icons[type] || 'info-circle';
    },

    /**
     * 确认对话框
     */
    confirm: function(message, title = '确认操作') {
        return new Promise((resolve) => {
            if (confirm(`${title}\n\n${message}`)) {
                resolve(true);
            } else {
                resolve(false);
            }
        });
    },

    /**
     * Toast消息
     */
    toast: function(message, type = 'info') {
        // 简单的toast实现，可以后续扩展
        const toastHtml = `
            <div class="toast align-items-center text-white bg-${type} border-0" role="alert">
                <div class="d-flex">
                    <div class="toast-body">${message}</div>
                    <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
                </div>
            </div>
        `;

        // 添加toast容器（如果不存在）
        if ($('#toast-container').length === 0) {
            $('body').append('<div id="toast-container" class="position-fixed top-0 end-0 p-3" style="z-index: 11;"></div>');
        }

        const $toast = $(toastHtml);
        $('#toast-container').append($toast);

        // 显示toast
        const toastBootstrap = new bootstrap.Toast($toast[0]);
        toastBootstrap.show();

        // 监听隐藏事件，移除元素
        $toast.on('hidden.bs.toast', function() {
            $(this).remove();
        });
    }
};

// 表单验证
const FormValidator = {
    /**
     * 验证必填字段
     */
    validateRequired: function(value, fieldName) {
        if (!value || value.toString().trim() === '') {
            return `${fieldName}不能为空`;
        }
        return null;
    },

    /**
     * 验证数字范围
     */
    validateRange: function(value, min, max, fieldName) {
        const num = parseFloat(value);
        if (isNaN(num)) {
            return `${fieldName}必须是有效数字`;
        }
        if (num < min || num > max) {
            return `${fieldName}必须在${min}到${max}之间`;
        }
        return null;
    },

    /**
     * 验证字符串长度
     */
    validateLength: function(value, minLength, maxLength, fieldName) {
        const str = value ? value.toString() : '';
        if (str.length < minLength) {
            return `${fieldName}长度不能少于${minLength}个字符`;
        }
        if (str.length > maxLength) {
            return `${fieldName}长度不能超过${maxLength}个字符`;
        }
        return null;
    },

    /**
     * 验证表单
     */
    validateForm: function(formData, rules) {
        const errors = {};
        
        for (const field in rules) {
            const fieldRules = rules[field];
            const value = formData[field];
            
            for (const rule of fieldRules) {
                const error = this[rule.type](value, ...rule.params);
                if (error) {
                    errors[field] = error;
                    break; // 只显示第一个错误
                }
            }
        }
        
        return {
            isValid: Object.keys(errors).length === 0,
            errors: errors
        };
    },

    /**
     * 显示表单错误
     */
    showFormErrors: function(errors) {
        // 清除之前的错误
        $('.is-invalid').removeClass('is-invalid');
        $('.invalid-feedback').remove();
        
        // 显示新错误
        for (const field in errors) {
            const $field = $(`[name="${field}"]`);
            if ($field.length > 0) {
                $field.addClass('is-invalid');
                $field.after(`<div class="invalid-feedback">${errors[field]}</div>`);
            }
        }
    }
};

// 本地存储管理
const Storage = {
    /**
     * 设置本地存储
     */
    set: function(key, value, expiry = null) {
        const data = {
            value: value,
            expiry: expiry ? Date.now() + expiry : null
        };
        localStorage.setItem(key, JSON.stringify(data));
    },

    /**
     * 获取本地存储
     */
    get: function(key, defaultValue = null) {
        try {
            const item = localStorage.getItem(key);
            if (!item) return defaultValue;
            
            const data = JSON.parse(item);
            
            // 检查是否过期
            if (data.expiry && Date.now() > data.expiry) {
                this.remove(key);
                return defaultValue;
            }
            
            return data.value;
        } catch (error) {
            console.error('读取本地存储失败:', error);
            return defaultValue;
        }
    },

    /**
     * 删除本地存储
     */
    remove: function(key) {
        localStorage.removeItem(key);
    },

    /**
     * 清空本地存储
     */
    clear: function() {
        localStorage.clear();
    }
};

// 页面加载完成后的初始化
$(document).ready(function() {
    // 初始化工具提示
    $('[data-bs-toggle="tooltip"]').tooltip();
    
    // 初始化弹出框
    $('[data-bs-toggle="popover"]').popover();
    
    // 自动关闭警告框
    $('.alert').each(function() {
        const $alert = $(this);
        if (!$alert.hasClass('alert-persistent')) {
            setTimeout(() => {
                $alert.alert('close');
            }, 5000);
        }
    });
    
    // 全局AJAX错误处理
    $(document).ajaxError(function(event, xhr, settings, thrownError) {
        console.error('AJAX请求失败:', {
            url: settings.url,
            status: xhr.status,
            error: thrownError
        });
        
        if (xhr.status === 401) {
            Notification.error('认证失败，请重新登录');
        } else if (xhr.status === 403) {
            Notification.error('权限不足，无法执行此操作');
        } else if (xhr.status === 404) {
            Notification.error('请求的资源不存在');
        } else if (xhr.status >= 500) {
            Notification.error('服务器内部错误，请稍后重试');
        }
    });
    
    // 表单自动验证
    $('form[data-validate="true"]').on('submit', function(e) {
        const $form = $(this);
        const isValid = $form[0].checkValidity();
        
        if (!isValid) {
            e.preventDefault();
            e.stopPropagation();
        }
        
        $form.addClass('was-validated');
    });
    
    // 自动保存表单数据
    $('form[data-autosave="true"]').each(function() {
        const $form = $(this);
        const formId = $form.attr('id') || 'form-' + Utils.generateUUID();
        
        // 加载保存的数据
        const savedData = Storage.get(`form-data-${formId}`);
        if (savedData) {
            for (const name in savedData) {
                const $field = $form.find(`[name="${name}"]`);
                if ($field.length > 0) {
                    $field.val(savedData[name]);
                }
            }
        }
        
        // 监听表单变化
        $form.on('change input', Utils.debounce(function() {
            const formData = {};
            $form.find('[name]').each(function() {
                const $field = $(this);
                formData[$field.attr('name')] = $field.val();
            });
            Storage.set(`form-data-${formId}`, formData, 24 * 60 * 60 * 1000); // 24小时过期
        }, 1000));
    });
});

// 导出到全局
window.Utils = Utils;
window.API = API;
window.Notification = Notification;
window.FormValidator = FormValidator;
window.Storage = Storage;